palette 动画模块编辑器 开发日志
开发 Animation 模块的阶段性总结,该模归属于Palette编辑器项目

关键帧动画是一种通过设置动画序列中关键时刻的状态变化,然后在这些关键帧之间自动生成过渡效果的动画技术。
动机与项目立项
“Animation”模块是“Palette”项目的核心部分之一,旨在提供强大且灵活的动画编辑功能。通过这个模块,用户可以创建、编辑和管理关键帧动画,赋予3D模型生命。关键帧动画是3D动画制作的基础,通过在时间线上设置关键的姿态或位置,系统会自动计算和补间中间帧,从而实现流畅的过渡效果。这一功能使得用户能够高效地制作复杂的动画序列,无需逐帧手动调整。
核心功能设计
在“Palette”的“Animation”模块中,关键帧动画的实现是其核心功能之一。关键帧动画的基本原理是通过在时间轴上的特定位置设置关键帧,这些关键帧包含了3D模型在某一时刻的具体状态,如位置、旋转、缩放等。
为了保证动画的流畅性和可控性,“Palette”采用了多种插值方法,如线性插值和贝塞尔曲线。线性插值可以创建均匀过渡的动画,而贝塞尔曲线则提供了更灵活的控制,可以实现更自然的运动轨迹。在开发过程中,如何平衡精确性与计算效率是一个关键挑战。
关键帧系统
实现添加、删除、修改关键帧的功能,并支持不同属性(位置、旋转、缩放等)的动画。
关键帧系统是动画编辑器的核心部分,它负责管理和处理动画中各个关键时刻的状态,并生成这些关键时刻之间的平滑过渡效果。这个系统需要处理以下几个关键方面:
关键帧,轨道的定义与管理
关键帧对象的抽象原型结构
abstract class KeyframeProto {
readonly abstract attribute: string;
time: number = 0;
value: Object3DAttributeData;
readonly parameterPositions: number[] = [];
readonly sampleValues: number[] = [];
readonly uuid: string;
readonly object: THREE.Object3D;
constructor(object: THREE.Object3D, time: number, value: Object3DAttributeData) {}
update() {}
}
KeyframeProto
类是一个关键帧的抽象原型类,定义了与关键帧相关的一些核心属性和方法,并且为派生类提供了基础结构。
- 关键帧的基本属性
attribute (string)
:attribute 是一个抽象的只读属性,用于指示这个关键帧所绑定的对象属性类型(例如位置、旋转等)。由于是抽象的,这个属性需要在派生类中具体实现,确保每个关键帧都能明确知道自己操作的是什么属性。 time (number):time 表示这个关键帧在动画中的时间点,通常以秒或帧数为单位。它决定了关键帧在时间轴上的位置。 value (Object3DAttributeData):value 存储了与这个关键帧相关的属性值(如位置坐标、旋转四元数等)。这个值可能是一个简单的数值,也可能是一个复杂的数据结构(例如 3D 坐标)。 uuid (string):uuid 是一个唯一标识符,用于标识每一个关键帧。它结合了对象的 UUID 和随机字符串,以确保每个关键帧的唯一性。 - 对象引用 object (THREE.Object3D):object 是 Three.js 中的 3D 对象的引用。每个关键帧都与一个特定的 3D 对象相关联,通过这个引用,可以访问和操作这个对象的属性。
- 插值数据
parameterPositions (number[])
:parameterPositions 是一个数组,用来存储与关键帧时间相关的参数位置。通常,在插值过程中,时间参数会映射到参数位置,以便生成平滑的过渡效果。sampleValues (number[])
:sampleValues 用来存储关键帧的采样值,这些值将用于插值计算。在动画播放时,系统会使用这些采样值进行插值,以计算两个关键帧之间的过渡状态。 - 构造函数
constructor(object: THREE.Object3D, time: number, value: Object3DAttributeData)
:构造函数初始化关键帧的基本属性,包括对象引用、时间点、属性值等。它还生成了 uuid 并填充了 sampleValues 和 parameterPositions 数组,以便在后续操作中使用。 - 更新方法
update()
:update 方法用于更新关键帧的采样值和参数位置。当关键帧的时间点或属性值发生变化时,这个方法可以确保关键帧的数据保持最新状态。它会清空并重新填充 sampleValues 和 parameterPositions 数组。 - 派生类的扩展 派生类:KeyframeProto 是一个抽象类,它定义了基本的接口和行为,但具体的实现留给了派生类。例如,ObjectKeyframe, QuaternionLinearKeyframe, QuaternionBufferKeyframe 等类可能会根据不同的动画属性(如位置、旋转等)实现不同的逻辑。
这个 KeyframeProto 类为关键帧系统提供了一个灵活的基础结构,支持多种类型的动画属性。通过抽象化 attribute 和 value 等关键属性,它为各种派生类提供了统一的接口,使得不同类型的关键帧可以在同一系统中无缝协作。同时,它还通过 update 方法保持数据的实时性,确保动画的精确性和一致性。
时间轴管理
开发可视化的时间轴,用于显示和操作动画关键帧的时间分布。
过渡效果生成
实现关键帧之间的自动补间(interpolation)算法,生成平滑的过渡动画。
视图设计
在设计“Animation”模块的用户界面时,我们的目标是实现功能性与直观性的平衡。我们希望即使是初学者也能快速上手,同时为高级用户提供足够的深度和灵活性。
模块的UI布局采用了时间轴为核心的设计,用户可以直观地查看和编辑关键帧的位置和内容。通过拖放操作,用户可以轻松地调整关键帧的时间和属性。此外,我们还加入了实时预览功能,允许用户在编辑过程中随时查看动画效果。这种即时反馈不仅提高了工作效率,也减少了反复调整的时间。